#include "qqmusic.h"
#include "ui_qqmusic.h"
#include "QMouseEvent"
#include"QGraphicsDropShadowEffect"
#include"QDebug"
#include"QList"
#include"QJsonObject"
#include "QJsonArray"
#include "time.h"
#include"volumetool.h"
#include"QDir"
#include"QFileDialog"
#include "musiclist.h"
#include<QMediaPlaylist>
#include"musicslider.h"
#include<QPropertyAnimation>
#include<QSqlDatabase>
#include<QMessageBox>
#include<QSqlQuery>
QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
{
    ui->setupUi(this);
    InitUI();
    InitsqlLite();
    InitMusicList();
    Initplayer();
    Connectform();
    randompropation();

}
VolumeTool* volume;
void QQMusic::InitUI()
{
    //设置阴影效果
    this->setWindowFlag(Qt::WindowType::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    QGraphicsDropShadowEffect* as=new QGraphicsDropShadowEffect(this);
    as->setOffset(0,0);
    as->setColor("#000000");
    as->setBlurRadius(10);
    setGraphicsEffect(as);
    //设置自定义空控件图片与文本
    ui->music_2->Seticonandtext(":/images/rec.png", "推荐",0);
    ui->audio->Seticonandtext(":/images/radio.png", "电台",1);
    ui->music->Seticonandtext(":/images/music.png", "音乐馆",2);
    ui->mylike->Seticonandtext(":/images/like.png", "我喜欢",3);
    ui->download->Seticonandtext(":/images/local.png", "本地下载",4);
    ui->recent->Seticonandtext(":/images/recent.png", "最近播放",5);
    ui->music_2->showanimt();
    ui->download->showanimt();
    ui->stackedWidget->setCurrentIndex(4);
    srand(time(NULL));
    ui->recMusicBox->InitrecboxUI(randompropation(),1);
    ui->supplyMusicBox->InitrecboxUI(randompropation(),2);
    // 创建⾳量调节窗⼝对象并挂到对象树
    volume = new VolumeTool(this);
    // 设置CommonPage的信息
     ui->page_4->setCommen("我喜欢", ":/images/ilikebg.png");
     ui->page_5->setCommen("本地⾳乐", ":/images/localbg.png");
     ui->page_6->setCommen("最近播放", ":/images/recentbg.png");
     //设置初始播放图片
     ui->pushButton_3->setIcon(QIcon(":/images/play3.png")); // 默认为暂停图标
     ui->pushButton->setIcon(QIcon(":/images/shuffle_2.png")); // 默认为随机播放
     currentpage=ui->page_5;
     lrcPage=new LrcPage(this);
     lrcPage->setGeometry(10,10,lrcPage->width(),lrcPage->height());
     lrcPage->hide();
     animation=new QPropertyAnimation(lrcPage,"geometry",this);
     animation->setDuration(250);
     animation->setStartValue(QRect(10,10+lrcPage->height(),lrcPage->width(),lrcPage->height()));
     animation->setEndValue(QRect(10,10,lrcPage->width(),lrcPage->height()));
     currentindex=-1;
}

void QQMusic::InitsqlLite()
{
    sqlite = QSqlDatabase::addDatabase("QSQLITE");
    sqlite.setDatabaseName("QQMusic.db");
    if(!sqlite.open())
    {
        QMessageBox::critical(this,"打开QQMusic.db失败",sqlite.lastError().text());
        return;
    }
    qDebug()<<"创建 [musicInfo] 表成功!!!";
    QString sql("CREATE TABLE IF NOT EXISTS musicInfo(\
                 id INTEGER PRIMARY KEY AUTOINCREMENT,\
                 musicId varchar(200) UNIQUE,\
                 musicName varchar(50),\
                 musicSinger varchar(50),\
                 albumName varchar(50),\
                 duration BIGINT,\
                 musicUrl varchar(256),\
                 isLike INTEGER,\
                 isHistory INTEGER)");
    QSqlQuery query;
    if(!query.exec(sql))
    {
        QMessageBox::critical(this, "创建数据库表失败", query.lastError().text());
        return;
    }
    qDebug()<<"SQLite连接成功，并创建 [QQMusic.db] 数据库!!!";
    qDebug()<<"创建 [musicInfo] 表成功!!!";
}

void QQMusic::InitMusicList()
{
    musicList.readFromDB();
    ui->page_4->setMusicListType(PageType::LIKE_PAGE);
    ui->page_4->reFresh(musicList);
    ui->page_5->setMusicListType(PageType::LOCAL_PAGE);
    ui->page_5->reFresh(musicList);
    ui->page_6->setMusicListType(PageType::HISTORY_PAGE);
    ui->page_6->reFresh(musicList);

}

void QQMusic::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        distance=event->globalPos()-frameGeometry().topLeft();
    }
    QWidget::mousePressEvent(event);
}

void QQMusic::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons()==Qt::LeftButton)
    {
        move(event->globalPos()-distance);
    }
    QWidget::mouseMoveEvent(event);
}

void QQMusic::onUpdateLikeMusic(bool isLike, QString musicId)
{
    //找到该首歌，更新music信息
    auto it=musicList.findMusicById(musicId);
    if(it!=musicList.end())
    {
        it->setIsLike(isLike);
    }
    //. 通知三个⻚⾯更新⾃⼰的数据
    ui->page_4->reFresh(musicList);
    ui->page_5->reFresh(musicList);
    ui->page_6->reFresh(musicList);
}

QJsonArray QQMusic::randompropation()
{
    QVector<QString> as;
    as<<"001.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"
     <<"007.png"
     <<"008.png"<<"009.png"<<"010.png"<<"011.png"<<"012.png"
     <<"013.png"
      <<"014.png"<<"015.png"<<"016.png"<<"017.png"<<"018.png"
     <<"019.png"
      <<"020.png"<<"021.png"<<"022.png"<<"023.png"<<"024.png"
     <<"025.png"
     <<"026.png"<<"027.png"<<"028.png"<<"029.png"<<"030.png"
     <<"031.png"
     <<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"
     <<"037.png"
     <<"038.png"<<"039.png"<<"040.png";
    std::random_shuffle(as.begin(),as.end());
    QJsonArray af;
    for(int i=0;i<as.size();i++)
    {
        QJsonObject sd;
        sd.insert("path:",":/images/rec/"+as[i]);
        QString strText=QString("推荐-%1").arg(i,3,10,QChar('0'));
        sd.insert("text:",strText);
        af.append(sd);
    }
    return af;
}

QQMusic::~QQMusic()
{
    delete ui;
}


void QQMusic::on_quit_clicked()
{
    musicList.writeToDB();
    sqlite.close();
    close();
}

void QQMusic::Connectform()
{
    connect(ui->music_2,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->audio,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->music,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->mylike,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->download,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->recent,&Form::btClick,this,&QQMusic::onbtClick);
    connect(ui->page_4,&Commen::updateLikeMusic,this,&QQMusic::onUpdateLikeMusic);
    connect(ui->page_5,&Commen::updateLikeMusic,this,&QQMusic::onUpdateLikeMusic);
    connect(ui->page_6,&Commen::updateLikeMusic,this,&QQMusic::onUpdateLikeMusic);
    connect(ui->pushButton_3,&QPushButton::clicked,this,&QQMusic::onPlayClicked);
    connect(fg,&QMediaPlayer::stateChanged,this,&QQMusic::onPlayChangedStatus);
    connect(ui->pushButton_2,&QPushButton::clicked,this,&QQMusic::OnPlayUpMusic);
    connect(ui->pushButton_4,&QPushButton::clicked,this,&QQMusic::OnPlayDownMusic);
    connect(ui->pushButton,&QPushButton::clicked,this,&QQMusic::OnPlayBackMode);
    connect(gh,&QMediaPlaylist::playbackModeChanged,this,&QQMusic::OnPlayBackModeChanged);
    connect(ui->page_4,&Commen::playAll,this,&QQMusic::OnPlayAll);
    connect(ui->page_5,&Commen::playAll,this,&QQMusic::OnPlayAll);
    connect(ui->page_6,&Commen::playAll,this,&QQMusic::OnPlayAll);
    connect(ui->page_4,&Commen::playMusicByIndex,this,&QQMusic::playMusicByIndex);
    connect(ui->page_5,&Commen::playMusicByIndex,this,&QQMusic::playMusicByIndex);
    connect(ui->page_6,&Commen::playMusicByIndex,this,&QQMusic::playMusicByIndex);
    connect(gh,&QMediaPlaylist::currentIndexChanged,this,&QQMusic::onCurrentIndexChanged);
    connect(volume,&VolumeTool::setslince,this,&QQMusic::setMusicSilence);
    connect(volume,&VolumeTool::setMusicVolume,this,&QQMusic::setplayerVolume);
    connect(ui->processbar,&MusicSlider::SetMusicSliderposition,this,&QQMusic::onSliderpositionChange);
    connect(ui->pushButton_7,&QPushButton::clicked,this,&QQMusic::onLrcWordClicked);
}

//void QQMusic::PlayOnMusic()
//{
//    fg->setMedia(musicList.begin()->getMusicUrl());
//    fg->play();
//}

void QQMusic::Initplayer()
{
    fg=new QMediaPlayer(this);
    gh=new QMediaPlaylist(this);
    gh->setPlaybackMode(QMediaPlaylist::Loop);
    fg->setPlaylist(gh);
    fg->setVolume(20);
    connect(fg,&QMediaPlayer::durationChanged,this,&QQMusic::onPlayDurationChange);
    connect(fg,&QMediaPlayer::positionChanged,this,&QQMusic::onPositionChange);
    connect(fg,&QMediaPlayer::metaDataAvailableChanged,this,&QQMusic::onMetaDataAvailableChangedChanged);
}

void QQMusic::onPlayClicked()
{
    if(fg->state()==QMediaPlayer::PlayingState)
    {
        fg->pause();
    }
    else if(fg->state()==QMediaPlayer::PausedState)
    {
        fg->play();
    }
    else if(fg->state() == QMediaPlayer::StoppedState)
    {
        fg->play();
    }
}

void QQMusic::onPlayChangedStatus()
{
    if(fg->state()==QMediaPlayer::PlayingState)
    {
        ui->pushButton_3->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        ui->pushButton_3->setIcon(QIcon(":/images/play3.png"));
    }
}

void QQMusic::OnPlayUpMusic()
{
    gh->previous();
}

void QQMusic::OnPlayDownMusic()
{
    gh->next();
}

void QQMusic::OnPlayBackMode()
{
    //设置播放模式
    if(gh->playbackMode()==QMediaPlaylist::Loop)
    {
        ui->pushButton->setToolTip("随机播放");
        gh->setPlaybackMode(QMediaPlaylist::Random);
    }
    else if(gh->playbackMode()==QMediaPlaylist::Random)
    {
        ui->pushButton->setToolTip("单曲循环");
        gh->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
    else if(gh->playbackMode()==QMediaPlaylist::CurrentItemInLoop)
    {
        ui->pushButton->setToolTip("列表循环");
         gh->setPlaybackMode(QMediaPlaylist::Loop);
    }
    else
    {
        qDebug()<<"播放模式错误";
    }
}

void QQMusic::OnPlayBackModeChanged(QMediaPlaylist::PlaybackMode playbackmode)
{
    if(playbackmode==QMediaPlaylist::Loop)
    {
        ui->pushButton->setIcon(QIcon(":/images/list_play.png"));
    }
    else if(playbackmode==QMediaPlaylist::Random)
    {
        ui->pushButton->setIcon(QIcon(":/images/shuffle_2.png"));
    }
    else if(playbackmode==QMediaPlaylist::CurrentItemInLoop)
    {
        ui->pushButton->setIcon(QIcon(":/images/single_play.png"));
    }
    else
    {
        qDebug()<<"暂不支持该模式";
    }
}

void QQMusic::OnPlayAll(PageType pagetype)
{
    Commen* page=nullptr;
    switch(pagetype)
    {
      case PageType::LIKE_PAGE:
        page=ui->page_4;
        break;
    case PageType::LOCAL_PAGE:
        page=ui->page_5;
        break;
    case PageType::HISTORY_PAGE:
        page=ui->page_6;
        break;
    default:
        qDebug()<<"扩占";
    }
    playAllCommenPage(page,0);
}

void QQMusic::playAllCommenPage(Commen *commenpage, int index)
{
    currentpage=commenpage;
    gh->clear();
    commenpage->addMusicToPlayer(musicList,gh);
    gh->setCurrentIndex(index);
    fg->play();
}

void QQMusic::playMusicByIndex(Commen *page, int index)
{
    playAllCommenPage(page,index);
}

void QQMusic::onCurrentIndexChanged(int index)
{
    currentindex=index;
    QString id=currentpage->getMusicIdByIndex(index);
    auto it=musicList.findMusicById(id);
    if(it!=musicList.end())
    {
        it->setIsHistory(true);
    }
    ui->page_6->reFresh(musicList);
}

void QQMusic::setMusicSilence(bool isMute)
{
    fg->setMuted(isMute);
}

void QQMusic::setplayerVolume(int Volume)
{
    fg->setVolume(Volume);
}

void QQMusic::onPlayDurationChange(qint64 duration)
{
    totaltime=duration;
    ui->label_15->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0')).arg(duration/1000%60,2,10,QChar('0')));
}

void QQMusic::onPositionChange(qint64 position)
{
    ui->label_13->setText(QString("%1:%2").arg(position/1000/60,2,10,QChar('0')).arg(position/1000%60,2,10,QChar('0')));
    ui->processbar->setStep((float)position/(float)totaltime);
    if(currentindex>=0)
    {
        lrcPage->showLrcWord(position);
    }
}

void QQMusic::onSliderpositionChange(float value)
{
    qDebug()<<"sdsad";
    qint64 as=(qint64)(value*totaltime);
    ui->label_13->setText(QString("%1:%2").arg(as/1000/60,2,10,QChar('0')).arg(as/1000%60,2,10,QChar('0')));
    fg->setPosition(as);
}

void QQMusic::onMetaDataAvailableChangedChanged(bool available)
{
    QString musicId = currentpage->getMusicIdByIndex(currentindex);
    auto it = musicList.findMusicById(musicId);

   QString musicName("未知歌曲");
   QString musicSinger("歌手位置");
   if(it != musicList.end())
   {
       musicName = it->getMusicName();
       musicSinger = it->getSingerName();
   }

   ui->label_10->setText(musicName);
   ui->label_11->setText(musicSinger);
    QVariant varient=fg->metaData("ThumbnailImage");
    if(varient.isValid())
    {
        QImage image=varient.value<QImage>();
        ui->label_9->setPixmap(QPixmap::fromImage(image));
        ui->label_9->setScaledContents(true);
        currentpage->setImageLabel(QPixmap::fromImage(image));
    }
    else
    {
        // 设置默认图⽚-修改
        QString path=":/images/rec/001.png";
        ui->label_9->setPixmap(path);
        ui->label_9->setScaledContents(true);
        currentpage->setImageLabel(path);
        qDebug()<<"歌曲没有封⾯图⽚";
    }
    if(it!=musicList.end())
    {
        lrcPage->parseLrc(it->getLrcFilePath());
    }
}

void QQMusic::onLrcWordClicked()
{
    lrcPage->show();
    animation->start();
}
void QQMusic::onbtClick(int pageid)
{
    ui->stackedWidget->setCurrentIndex(pageid);
    //消除其他按钮的颜色
    QList<Form*> as=this->findChildren<Form*>();
    for(auto e:as)
    {
        if(e->getid()!=pageid)
        {
            e->changebackground();
        }
    }
}

void QQMusic::on_pushButton_5_clicked()
{
    // 先要调整窗⼝的显⽰位置，否则该窗⼝在主窗⼝的左上⻆
    // 1. 获取该按钮左上⻆的图标
    QPoint point=ui->pushButton_5->mapToGlobal(QPoint(0,0));
    // 2. 计算volume窗⼝的左上⻆位置
    // 让该窗⼝显⽰在⿏标点击的正上⽅
    // ⿏标位置：减去窗⼝宽度的⼀半，以及⾼度恰巧就是窗⼝的左上⻆
    QPoint ad=point-QPoint(volume->width()/2,volume->height());
    // 微调窗⼝位置
    ad.setY(ad.y()+30);
    ad.setX(ad.x()+15);
    // 3. 移动窗⼝位置
    volume->move(ad);
    // 4. 将窗⼝显⽰出来
    volume->show();
}

void QQMusic::on_pushButton_6_clicked()
{
    // 1. 创建⼀个⽂件对话框
    QFileDialog filedialog(this);
    filedialog.setWindowTitle("添加本地⾳乐");
    // 2. 创建⼀个打开格式的⽂件对话框
    filedialog.setAcceptMode(QFileDialog::AcceptOpen);
    // 3. 设置对话框模式
    // 只能选择⽂件，并且⼀次性可以选择多个存在的⽂件
    filedialog.setFileMode(QFileDialog::ExistingFiles);
    // 4. 设置对话框的MIME过滤器
    QStringList as;
    as<<"application/octet-stream";
    filedialog.setMimeTypeFilters(as);
    // 5. 设置对话框默认的打开路径,设置⽬录为当前⼯程所在⽬录
    QDir dir(QDir::currentPath());
    dir.cdUp();
    QString ad=dir.path()+"/QQMusic/musics/";
    qDebug()<<ad;
    filedialog.setDirectory(ad);
    // 6. 显⽰对话框，并接收返回值
    // 模态对话框, exec内部是死循环处理
    if(filedialog.exec()==QDialog::Accepted)
    {
        // 切换到本地⾳乐界⾯，因为加载完的⾳乐需要在本地⾳乐界⾯显⽰
        ui->stackedWidget->setCurrentIndex(4);
        // 获取对话框的返回值
        QList<QUrl> ret=filedialog.selectedUrls();
        // 拿到歌曲⽂件后，将歌曲⽂件交由musicList进⾏管理
        musicList.addMusicByUrl(ret);
        // 更新到本地⾳乐列表
        ui->page_5->reFresh(musicList);
        ui->page_5->addMusicToPlayer(musicList,gh);
    }
}
